﻿using System;
using System.Collections.Generic;
using System.Diagnostics.Contracts;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;
using System.IO;
using System.Linq;
using MvcGraffiti.Models;
using Point = System.Drawing.Point;

namespace MvcGraffiti.Core
{
	public class ThumbnailGenerator
	{
		public static bool Generate(int width, int height, IEnumerable<Stroke> strokes, decimal zoom, string path)
		{
			var result = false;
			using(var bitmap = Render(width,height,strokes))
			{
				using(var thumb = Resize(bitmap,zoom))
				{
					result = Save(thumb, path);
				}
			}

			return result;
		}

		public static Bitmap Render(int width, int height, IEnumerable<Stroke> strokes)
		{
			var bitmap = new Bitmap(width, height, PixelFormat.Format32bppArgb);
			using (var graphics = Graphics.FromImage(bitmap))
			{
				graphics.PixelOffsetMode = PixelOffsetMode.HighQuality;
				graphics.FillRectangle(Brushes.White, 0, 0, width, height);

				foreach (var stroke in strokes.Where(s=>s.Points.Count()>1))
				{
					if(stroke.Type == "pen")
					{
						var srgb = stroke.Color.Trim('#');
                        var irgb = Enumerable.Range(0, 3).Select(i => Convert.ToInt32(srgb.Substring(i * 2, 2), 16)).ToArray();
						var color = Color.FromArgb(irgb[0], irgb[1], irgb[2]);
                        using (var pen = new Pen(color, Convert.ToSingle(stroke.Weight)))
                        {
                            graphics.DrawLines(pen, stroke.Points.Select(p => new Point(p.X, p.Y)).ToArray());
                        }
					}
				}
			}

			return bitmap;
		}

		public static Bitmap Resize(Bitmap bitmap, decimal zoom)
		{
			Contract.Requires(zoom>0);

			var width = (int)Math.Round(bitmap.Width * zoom);
			var height = (int)Math.Round(bitmap.Height * zoom);

			Bitmap zoomBitmap = new Bitmap(width, height, PixelFormat.Format32bppArgb);
			using (Graphics g = Graphics.FromImage(zoomBitmap))
			{
				g.FillRectangle(Brushes.White, 0, 0, width, height);
				InterpolationMode p_im = InterpolationMode.HighQualityBicubic;
				var im = InterpolationMode.HighQualityBilinear;
				//im = InterpolationMode.NearestNeighbor;
				g.InterpolationMode = im;
				g.DrawImage(bitmap, 0, 0, width, height);
			}

			return zoomBitmap;
		}

		public static bool Save(Bitmap bitmap, string path)
		{
			// あったら消す
			if(File.Exists(path))
				File.Delete(path);

            //var temp = Path.GetTempFileName();
            //bitmap.Save(temp, ImageFormat.Png);
            //File.Move(temp, path);
            bitmap.Save(path, ImageFormat.Png);
			return File.Exists(path);
		}
	}
}